package com.app.module.camera.ui

import android.annotation.SuppressLint
import android.graphics.SurfaceTexture
import android.hardware.SensorManager
import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import com.app.module.camera.R
import com.app.module.camera.ext.*
import com.app.module.camera.renderer.filter.func.SepiaRenderer
import com.app.module.camera.CameraMapper
import com.app.module.camera.permission.Permission
import com.app.module.camera.renderer.filter.func.VignetteRenderer
import com.app.module.camera.renderer.group.GroupRenderer
import com.app.module.camera.view.CameraTextureView

class Camera2Activity : AppCompatActivity() {

    private val permissio = Permission()
    private lateinit var mOrientationEventListener: OrientationEventListener

    private var mPreview: CameraMapper? = null

    var mLastHandledOrientation = 0

    @SuppressLint("MissingSuperCall")
    override fun onCreate(savedInstanceState: Bundle?) {
        window.addFlags(
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
                WindowManager.LayoutParams.FLAG_FULLSCREEN
        )
        super.onCreate(savedInstanceState)
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        initVariables()
        supportActionBar?.hide()
        setupOrientationEventListener()
    }

    override fun onResume() {
        super.onResume()
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        if (hasStorageAndCameraPermissions()) {
            mOrientationEventListener.enable()
        }
        runOnUiThread {
            tryInitCamera()
        }
    }

    override fun onPause() {
        super.onPause()
        window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        if (!hasStorageAndCameraPermissions()) {
            return
        }
        mOrientationEventListener.disable()
    }

    override fun onDestroy() {
        super.onDestroy()
        mPreview = null
    }

    private fun initVariables() {
        mLastHandledOrientation = 0
        if (appConfig.alwaysOpenBackCamera) {
            appConfig.lastUsedCamera = backCameraId.toString()
        }
    }

    private fun tryInitCamera() {
        permissio.handlePermission(this, PERMISSION_CAMERA) { camera ->
            if (camera) {
                permissio.handlePermission(this, PERMISSION_WRITE_STORAGE) { storage ->
                    if (storage) {
                        initializeCamera()
                    } else {
                        toast(R.string.no_storage_permissions)
                        finish()
                    }
                }
            } else {
                toast(R.string.no_camera_permissions)
                finish()
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        permissio.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    var settings = lazy {
        findViewById<ImageView>(R.id.settings)
    }
    var btn_holder = lazy {
        findViewById<LinearLayout>(R.id.btn_holder)
    }
    var take_image = lazy {
        findViewById<TextView>(R.id.take_image)
    }
    var take_video = lazy {
        findViewById<TextView>(R.id.take_video)
    }
    var switch_camera = lazy {
        findViewById<TextView>(R.id.switch_camera)
    }
    var surface_view = lazy {
        findViewById<CameraTextureView>(R.id.surface_view)
    }

    private fun initializeCamera() {
        setContentView(R.layout.activity_camera2)
        mPreview = CameraMapper(this)
        settings.value.setOnClickListener {
            val visible = btn_holder.value.isVisible
            if (visible) {
                btn_holder.value.visibility = View.GONE
            } else {
                btn_holder.value.visibility = View.VISIBLE
            }
        }

        take_image.value.setOnClickListener {
            permissio.handlePermission(this, PERMISSION_WRITE_STORAGE) { storage1 ->
                if (storage1) {
                    permissio.handlePermission(this, PERMISSION_READ_STORAGE) { storage2 ->
                        if (storage2) {
                            mPreview?.captureImage()
                        } else {
                            toast(R.string.no_storage_permissions)
                            finish()
                        }
                    }
                } else {
                    toast(R.string.no_storage_permissions)
                    finish()
                }
            }
        }

        take_video.value.setOnClickListener {
            permissio.handlePermission(this, PERMISSION_WRITE_STORAGE) { write_storage ->
                if (write_storage) {
                    permissio.handlePermission(this, PERMISSION_READ_STORAGE) { read_storage ->
                        if (read_storage) {
                            permissio.handlePermission(this, PERMISSION_RECORD_AUDIO) { audio ->
                                if (audio) {
                                    mPreview?.also { p ->
                                        if (p.isVideoRecording()) {
                                            p.capturevideoOver()
                                        } else {
                                            p.captureVideo()
                                        }
                                    }
                                } else {
                                    toast("授予音频权限")
                                    finish()
                                }
                            }
                        } else {
                            toast("文件读取权限")
                            finish()
                        }
                    }
                } else {
                    toast("文件写入权限")
                    finish()
                }
            }

        }
        switch_camera.value.setOnClickListener {
            mPreview?.switchCamera()
        }

        surface_view.value.surfaceTextureListener = object : TextureView.SurfaceTextureListener {

            override fun onSurfaceTextureSizeChanged(
                surface: SurfaceTexture,
                width: Int,
                height: Int
            ) {
                Log.e("Camera2Activity", "Activity -> onSurfaceTextureSizeChanged  $width  $height")
                mPreview?.setPreviewChange(surface, width, height)
                mPreview?.open()
            }

            override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {

            }

            override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
                Log.e("Camera2Activity", "Activity -> onSurfaceTextureDestroyed")
                mPreview?.close()
                return true
            }

            override fun onSurfaceTextureAvailable(
                surface: SurfaceTexture,
                width: Int,
                height: Int
            ) {
                Log.e("Camera2Activity", "Activity -> onSurfaceTextureAvailable  $width  $height")
                mPreview?.setRenderer(GroupRenderer(resources).apply {
                    addRenderer(VignetteRenderer(resources))
                    addRenderer(SepiaRenderer(resources))
                })
                mPreview?.setCameraChange(surface, width, height)
            }

        }
    }

    private fun hasStorageAndCameraPermissions() =
        hasPermission(PERMISSION_WRITE_STORAGE) && hasPermission(PERMISSION_CAMERA)

    private fun setupOrientationEventListener() {
        mOrientationEventListener =
            object : OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
                override fun onOrientationChanged(orientation: Int) {
                    if (isDestroyed) {
                        mOrientationEventListener.disable()
                        return
                    }

                    val currOrient = when (orientation) {
                        in 75..134 -> ORIENT_LANDSCAPE_RIGHT
                        in 225..289 -> ORIENT_LANDSCAPE_LEFT
                        else -> ORIENT_PORTRAIT
                    }

                    if (currOrient != mLastHandledOrientation) {
                        val degrees = when (currOrient) {
                            ORIENT_LANDSCAPE_LEFT -> 90
                            ORIENT_LANDSCAPE_RIGHT -> -90
                            else -> 0
                        }
                        mLastHandledOrientation = currOrient
                    }
                }
            }
    }

    fun setAspectRatio(width: Int, height: Int) {
        runOnUiThread {
            surface_view.value.setAspectRatio(width, height)
            surface_view.value.post {
                Log.e(
                    "Camera2Activity",
                    "setAspectRatio $width  $height    ${surface_view.value.width}  ${surface_view.value.height}"
                )
            }
        }
    }

}
